﻿window.crucible = window.crucible || {};

window.crucible.datacontext = (function (ko) {

    var datacontext = {
        createNode: createNode,
        hydrateNode: hydrateNode,
        saveStub: saveStub,
        saveDraft: saveDraft,
        publish: publish,
        quickFind: quickFind,
        loadComments: loadComments,
        fetchTree: fetchTree,
        saveComment: saveComment,
        putComment: putComment,
        deleteComment: deleteComment,
        putNodeVote: putNodeVote
        //nodeManager: new crucible.NodeManager()
    };

    return datacontext;


    function createNode(data) {
        return new datacontext.Node(data); // Node is injected by ko.node.model.js
    }
    
    function hydrateNode(node, callback) {
        if (node.Id === "starter") return;

        $.ajax({
            url: "/api/N/GetNode/" + node.Id,
            type: "GET",
            success: function (result) {
                node.freshData(result.node, result.parents);
                if (node.original && result.parents) {
                    node.original.setOtherParents(result.parents);
                }
                node.hydrated = true;
                if (callback) {
                    callback(result);
                }
            }
        });
    }
    
    function saveStub(title, body, type, callback) {

        $.ajax({
            url: "/api/N/SaveDraft?sendTree=false",
            type: "POST",
            data: {
                Id: 0,
                Title: title || "Untitled",
                Body: body || "This assertion is a stub.",
                Type: type,
                Published: false
            },
            success: function (stub) {

                //var props = {}; // Log event to mixpanel
                //props[crucible.mixprops.nodeId] = stub.Id;
                //props[crucible.mixprops.nodeTitle] = stub.Title;
                //mixpanel.track(crucible.mixevents.saveStub, props);

                if (callback) {
                    callback(stub);
                }
            }
        });

    }


    function saveDraft(node, callback) {

        var url = "/api/N/SaveDraft?sendTree=true";
        var source = node.Source();
        if (source && source.Id) {
            url += "&sourceId=" + source.Id;
        }

        $.ajax({
            url: url,
            type: "POST",
            data: {
                Id: node.Id,
                Title: node.Title() || "Untitled",
                Type: node.Type() || 1,
                Published: false,
                Body: node.Body(),
                Link: node.Link()
            },
            success: function (treeData) {
                node.freshData(treeData.root, treeData.rootParents);

                $.pnotify({ title: "Success", text: "Draft saved.", type: 'success' });

                //var props = {}; // Log event to mixpanel
                //props[crucible.mixprops.nodeId] = treeData.root.Id;
                //props[crucible.mixprops.nodeTitle] = treeData.root.Title;
                //props[crucible.mixprops.nodeType] = crucible.NodeTypeName(treeData.root.Type);
                //mixpanel.track(crucible.mixevents.saveDraft, props);
                
                if (callback) {
                    callback(treeData);
                }
            },
            error: function (a, b, message) {
                crucible.raiseError(message, true, false);
            }
        });

    }
    
    function fetchTree(id, callback) {

        var url = "/api/N/GetTree/" + id;
        
        $.ajax({
            url: url,
            type: "GET",
            success: function (treeData) {
            
                if (callback) {
                    callback(treeData);
                }
            },
            error: function (a, b, message) {
                crucible.raiseError(message, true, false);
            }
        });

    }
    
    function publish(node, successCallback, errorCallback) {

        var url = "/api/N/Publish";
        var source = node.Source();
        if (source && source.Id) {
            url += "?sourceId=" + source.Id;
        }

        $.ajax({
            url: url,
            type: "POST",
            data: {
                Id: node.Id,
                Title: node.Title(),
                Type: node.Type() || 1,
                Published: node.Published(),
                Body: node.Body(),
                Link: node.Link()
            },
            success: function (treeData) {

                if (treeData.publishProblems) {
                    errorCallback(treeData);
                } else {

                    node.freshData(treeData.root);

                    $.pnotify({ title: "Success", text: "Node published.", type: 'success' });

                    //var props = {}; // Log event to mixpanel
                    //props[crucible.mixprops.nodeId] = treeData.root.Id;
                    //props[crucible.mixprops.nodeTitle] = treeData.root.Title;
                    //props[crucible.mixprops.nodeType] = crucible.NodeTypeName(treeData.root.Type);
                    //mixpanel.track(crucible.mixevents.publish, props);

                    if (successCallback) {
                        successCallback(treeData);
                    }
                }
            },
            error: function (a, b, message) {

                crucible.raiseError(message, true, false);
                
            }
        });

    }
    
    function quickFind(searchText, maxResults, typeMask, callback) {
        $.ajax({
            url: "/api/QuickFind/Nodes",
            type: "GET",
            dataType: "json",
            data: { searchText: searchText, maxResults: maxResults, typeMask: typeMask },
            success: function (data) {
                if (callback) {
                    callback(data);
                }
            },
            error: function (jqXhr, textStatus, errorThrown) {
                crucible.raiseError(errorThrown, true, false);
            }
        });
    }
    
    function loadComments (node, callback) {

        $.ajax({
            url: "/api/Comment/NodeComments/" + node.Id,
            type: "GET",
            dataType: 'json',
            //data: { id: assertionId },
            success: function (commentData) {
                if (callback) {
                    callback(commentData);
                }
            }
        });
    }
    
    function saveComment(nodeId, body, parentId, callback) {
        $.ajax({
            url: "/api/Comment",
            type: "POST",
            dataType: 'json',
            data: {
                Body: body,
                Parent_Id: parentId,
                Node_Id: nodeId,
                Author_UserId: crucible.userId
            },
            success: function (response) {
                if (callback) {
                    callback(response);
                }
            }
        });
    }
    
    function putComment(comment, callback) {
        $.ajax({
            url: "/api/Comment/" + comment.Id,
            type: "PUT",
            dataType: 'json',
            data: {
                Id: comment.Id,
                Body: comment.BodyEdit
            },
            success: function (response) {
                if (callback) {
                    callback(response);
                }
            }
        });
    }
    
    function deleteComment(id, callback) {
        $.ajax({
            url: "/api/Comment/" + id,
            type: "DELETE",
            dataType: 'json',
            success: function (response) {
                if (callback) {
                    callback(response);
                }
            }
        });
    }
    
    function putNodeVote(nodeId, agreement, logic, callback) {
        $.ajax({
            url: "/api/NodeVote/",
            type: "PUT",
            dataType: 'json',
            data: {
                Author_UserId: crucible.userId,
                Node_Id: nodeId,
                Agreement: agreement,
                Logic: logic
            },
            success: function (response) {
                if (callback) {
                    callback(response);
                }
            }
        });
    }

})(ko);